-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[VPlan] Add VPSymbolicValueSC for typed VPValues w/o underlying IR value #130507
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-vectorizers Author: Florian Hahn (fhahn) ChangesThis introduces a new VPSymbolicValueSC to be used for typed live-in VPValues without underlying IR. VPValue is updated to store either the type or an underlying value in an union. This allows keeping the size of VPValue unchanged. The main motivation for adding the type is to not require passing the canonical IV type to VPTypeAnalysis. While with this patch, we still need to pass the LLVMContext, this can also be removed in a future patch (see Full diff: https://github.com/llvm/llvm-project/pull/130507.diff 11 Files Affected:
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index b987863127994..54a4b74642e23 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -4478,7 +4478,7 @@ void LoopVectorizationPlanner::emitInvalidCostRemarks(
static bool willGenerateVectors(VPlan &Plan, ElementCount VF,
const TargetTransformInfo &TTI) {
assert(VF.isVector() && "Checking a scalar VF?");
- VPTypeAnalysis TypeInfo(Plan.getCanonicalIV()->getScalarType());
+ VPTypeAnalysis TypeInfo(Plan.getCanonicalIV()->getScalarType()->getContext());
DenseSet<VPRecipeBase *> EphemeralRecipes;
collectEphemeralRecipesForVPlan(Plan, EphemeralRecipes);
// Set of already visited types.
@@ -9069,7 +9069,7 @@ static VPInstruction *addResumePhiRecipeForInduction(
/// \p IVEndValues.
static void addScalarResumePhis(VPRecipeBuilder &Builder, VPlan &Plan,
DenseMap<VPValue *, VPValue *> &IVEndValues) {
- VPTypeAnalysis TypeInfo(Plan.getCanonicalIV()->getScalarType());
+ VPTypeAnalysis TypeInfo(Plan.getCanonicalIV()->getScalarType()->getContext());
auto *ScalarPH = Plan.getScalarPreheader();
auto *MiddleVPBB = cast<VPBasicBlock>(ScalarPH->getSinglePredecessor());
VPRegionBlock *VectorRegion = Plan.getVectorLoopRegion();
@@ -9312,7 +9312,8 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
return !CM.requiresScalarEpilogue(VF.isVector());
},
Range);
- auto Plan = std::make_unique<VPlan>(OrigLoop);
+ auto Plan =
+ std::make_unique<VPlan>(OrigLoop, Legal->getWidestInductionType());
// Build hierarchical CFG.
// Convert to VPlan-transform and consoliate all transforms for VPlan
// creation.
@@ -9618,7 +9619,8 @@ VPlanPtr LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
assert(EnableVPlanNativePath && "VPlan-native path is not enabled.");
// Create new empty VPlan
- auto Plan = std::make_unique<VPlan>(OrigLoop);
+ auto Plan =
+ std::make_unique<VPlan>(OrigLoop, Legal->getWidestInductionType());
// Build hierarchical CFG
VPlanHCFGBuilder HCFGBuilder(OrigLoop, LI, *Plan);
HCFGBuilder.buildHierarchicalCFG();
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp
index 944a11b96325d..60708adfc7c55 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp
@@ -221,7 +221,7 @@ VPTransformState::VPTransformState(const TargetTransformInfo *TTI,
Loop *CurrentParentLoop, Type *CanonicalIVTy)
: TTI(TTI), VF(VF), CFG(DT), LI(LI), Builder(Builder), ILV(ILV), Plan(Plan),
CurrentParentLoop(CurrentParentLoop), LVer(nullptr),
- TypeAnalysis(CanonicalIVTy) {}
+ TypeAnalysis(CanonicalIVTy->getContext()) {}
Value *VPTransformState::get(const VPValue *Def, const VPLane &Lane) {
if (Def->isLiveIn())
@@ -847,7 +847,8 @@ void VPRegionBlock::print(raw_ostream &O, const Twine &Indent,
}
#endif
-VPlan::VPlan(Loop *L) {
+VPlan::VPlan(Loop *L, Type *InductionTy)
+ : VectorTripCount(InductionTy), VF(InductionTy), VFxUF(InductionTy) {
setEntry(createVPIRBasicBlock(L->getLoopPreheader()));
ScalarHeader = createVPIRBasicBlock(L->getHeader());
@@ -858,7 +859,7 @@ VPlan::VPlan(Loop *L) {
}
VPlan::~VPlan() {
- VPValue DummyValue;
+ VPValue DummyValue((Type *)nullptr);
for (auto *VPB : CreatedBlocks) {
if (auto *VPBB = dyn_cast<VPBasicBlock>(VPB)) {
@@ -888,10 +889,10 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
IRBuilder<> Builder(State.CFG.PrevBB->getTerminator());
auto *TCMO = Builder.CreateSub(TripCountV, ConstantInt::get(TCTy, 1),
"trip.count.minus.1");
- BackedgeTakenCount->setUnderlyingValue(TCMO);
+ BackedgeTakenCount->replaceAllUsesWith(getOrAddLiveIn(TCMO));
}
- VectorTripCount.setUnderlyingValue(VectorTripCountV);
+ VectorTripCount.replaceAllUsesWith(getOrAddLiveIn(VectorTripCountV));
IRBuilder<> Builder(State.CFG.PrevBB->getTerminator());
// FIXME: Model VF * UF computation completely in VPlan.
@@ -900,12 +901,13 @@ void VPlan::prepareToExecute(Value *TripCountV, Value *VectorTripCountV,
unsigned UF = getUF();
if (VF.getNumUsers()) {
Value *RuntimeVF = getRuntimeVF(Builder, TCTy, State.VF);
- VF.setUnderlyingValue(RuntimeVF);
- VFxUF.setUnderlyingValue(
+ VF.replaceAllUsesWith(getOrAddLiveIn(RuntimeVF));
+ VFxUF.replaceAllUsesWith(getOrAddLiveIn(
UF > 1 ? Builder.CreateMul(RuntimeVF, ConstantInt::get(TCTy, UF))
- : RuntimeVF);
+ : RuntimeVF));
} else {
- VFxUF.setUnderlyingValue(createStepForVF(Builder, TCTy, State.VF, UF));
+ VFxUF.replaceAllUsesWith(
+ getOrAddLiveIn(createStepForVF(Builder, TCTy, State.VF, UF)));
}
}
@@ -1166,7 +1168,8 @@ VPlan *VPlan::duplicate() {
return VPIRBB && VPIRBB->getIRBasicBlock() == ScalarHeaderIRBB;
}));
// Create VPlan, clone live-ins and remap operands in the cloned blocks.
- auto *NewPlan = new VPlan(cast<VPBasicBlock>(NewEntry), NewScalarHeader);
+ auto *NewPlan = new VPlan(cast<VPBasicBlock>(NewEntry), NewScalarHeader,
+ getCanonicalIV()->getScalarType());
DenseMap<VPValue *, VPValue *> Old2NewVPValues;
for (VPValue *OldLiveIn : getLiveIns()) {
Old2NewVPValues[OldLiveIn] =
@@ -1176,7 +1179,7 @@ VPlan *VPlan::duplicate() {
Old2NewVPValues[&VF] = &NewPlan->VF;
Old2NewVPValues[&VFxUF] = &NewPlan->VFxUF;
if (BackedgeTakenCount) {
- NewPlan->BackedgeTakenCount = new VPValue();
+ NewPlan->BackedgeTakenCount = new VPValue((Type *)nullptr);
Old2NewVPValues[BackedgeTakenCount] = NewPlan->BackedgeTakenCount;
}
assert(TripCount && "trip count must be set");
@@ -1379,6 +1382,11 @@ static bool isDefinedInsideLoopRegions(const VPValue *VPV) {
DefR->getParent()->getEnclosingLoopRegion());
}
+Type *VPValue::getType() const {
+ assert(isLiveIn());
+ return SubclassID == VPSymbolicValueSC ? Ty : getUnderlyingValue()->getType();
+}
+
bool VPValue::isDefinedOutsideLoopRegions() const {
return !isDefinedInsideLoopRegions(this);
}
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index f68a2283c0c79..a40d4cc8c7d10 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -3475,8 +3475,9 @@ class VPlan {
/// Construct a VPlan with \p Entry to the plan and with \p ScalarHeader
/// wrapping the original header of the scalar loop.
- VPlan(VPBasicBlock *Entry, VPIRBasicBlock *ScalarHeader)
- : Entry(Entry), ScalarHeader(ScalarHeader) {
+ VPlan(VPBasicBlock *Entry, VPIRBasicBlock *ScalarHeader, Type *InductionTy)
+ : Entry(Entry), ScalarHeader(ScalarHeader), VectorTripCount(InductionTy),
+ VF(InductionTy), VFxUF(InductionTy) {
Entry->setPlan(this);
assert(ScalarHeader->getNumSuccessors() == 0 &&
"scalar header must be a leaf node");
@@ -3486,11 +3487,12 @@ class VPlan {
/// Construct a VPlan for \p L. This will create VPIRBasicBlocks wrapping the
/// original preheader and scalar header of \p L, to be used as entry and
/// scalar header blocks of the new VPlan.
- VPlan(Loop *L);
+ VPlan(Loop *L, Type *InductionTy);
/// Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock
/// wrapping \p ScalarHeaderBB and a trip count of \p TC.
- VPlan(BasicBlock *ScalarHeaderBB, VPValue *TC) {
+ VPlan(BasicBlock *ScalarHeaderBB, VPValue *TC, Type *InductionTy)
+ : VectorTripCount(InductionTy), VF(InductionTy), VFxUF(InductionTy) {
setEntry(createVPBasicBlock("preheader"));
ScalarHeader = createVPIRBasicBlock(ScalarHeaderBB);
TripCount = TC;
@@ -3582,7 +3584,7 @@ class VPlan {
/// The backedge taken count of the original loop.
VPValue *getOrCreateBackedgeTakenCount() {
if (!BackedgeTakenCount)
- BackedgeTakenCount = new VPValue();
+ BackedgeTakenCount = new VPValue(getCanonicalIV()->getScalarType());
return BackedgeTakenCount;
}
diff --git a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
index 6f6875f0e5e0e..7a4cf7f0e8ca1 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
@@ -224,13 +224,8 @@ Type *VPTypeAnalysis::inferScalarType(const VPValue *V) {
if (Type *CachedTy = CachedTypes.lookup(V))
return CachedTy;
- if (V->isLiveIn()) {
- if (auto *IRValue = V->getLiveInIRValue())
- return IRValue->getType();
- // All VPValues without any underlying IR value (like the vector trip count
- // or the backedge-taken count) have the same type as the canonical IV.
- return CanonicalIVTy;
- }
+ if (V->isLiveIn())
+ return V->getType();
Type *ResultTy =
TypeSwitch<const VPRecipeBase *, Type *>(V->getDefiningRecipe())
diff --git a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.h b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.h
index cc21870bee2e3..7d4771d178924 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.h
@@ -39,10 +39,6 @@ class Type;
/// of the previously inferred types.
class VPTypeAnalysis {
DenseMap<const VPValue *, Type *> CachedTypes;
- /// Type of the canonical induction variable. Used for all VPValues without
- /// any underlying IR value (like the vector trip count or the backedge-taken
- /// count).
- Type *CanonicalIVTy;
LLVMContext &Ctx;
Type *inferScalarTypeForRecipe(const VPBlendRecipe *R);
@@ -55,8 +51,7 @@ class VPTypeAnalysis {
Type *inferScalarTypeForRecipe(const VPReplicateRecipe *R);
public:
- VPTypeAnalysis(Type *CanonicalIVTy)
- : CanonicalIVTy(CanonicalIVTy), Ctx(CanonicalIVTy->getContext()) {}
+ VPTypeAnalysis(LLVMContext &Ctx) : Ctx(Ctx) {}
/// Infer the type of \p V. Returns the scalar type of \p V.
Type *inferScalarType(const VPValue *V);
diff --git a/llvm/lib/Transforms/Vectorize/VPlanHelpers.h b/llvm/lib/Transforms/Vectorize/VPlanHelpers.h
index 8bdbf556efbb3..4a16f08192147 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanHelpers.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanHelpers.h
@@ -375,8 +375,8 @@ struct VPCostContext {
VPCostContext(const TargetTransformInfo &TTI, const TargetLibraryInfo &TLI,
Type *CanIVTy, LoopVectorizationCostModel &CM,
TargetTransformInfo::TargetCostKind CostKind)
- : TTI(TTI), TLI(TLI), Types(CanIVTy), LLVMCtx(CanIVTy->getContext()),
- CM(CM), CostKind(CostKind) {}
+ : TTI(TTI), TLI(TLI), Types(CanIVTy->getContext()),
+ LLVMCtx(CanIVTy->getContext()), CM(CM), CostKind(CostKind) {}
/// Return the cost for \p UI with \p VF using the legacy cost model as
/// fallback until computing the cost of all recipes migrates to VPlan.
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 7646350ca0ed2..c8d522fca46a6 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -545,7 +545,7 @@ createScalarIVSteps(VPlan &Plan, InductionDescriptor::InductionKind Kind,
// Truncate base induction if needed.
Type *CanonicalIVType = CanonicalIV->getScalarType();
- VPTypeAnalysis TypeInfo(CanonicalIVType);
+ VPTypeAnalysis TypeInfo(CanonicalIVType->getContext());
Type *ResultTy = TypeInfo.inferScalarType(BaseIV);
if (TruncI) {
Type *TruncTy = TruncI->getType();
@@ -751,7 +751,7 @@ void VPlanTransforms::optimizeInductionExitUsers(
assert(PredVPBB == Plan.getMiddleBlock() &&
"predecessor must be the middle block");
- VPTypeAnalysis TypeInfo(Plan.getCanonicalIV()->getScalarType());
+ VPTypeAnalysis TypeInfo(Plan.getCanonicalIV()->getScalarType()->getContext());
VPBuilder B(Plan.getMiddleBlock()->getTerminator());
for (VPRecipeBase &R : *ExitVPBB) {
auto *ExitIRI = cast<VPIRInstruction>(&R);
@@ -944,8 +944,11 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
#ifndef NDEBUG
// Verify that the cached type info is for both A and its users is still
// accurate by comparing it to freshly computed types.
- VPTypeAnalysis TypeInfo2(
- R.getParent()->getPlan()->getCanonicalIV()->getScalarType());
+ VPTypeAnalysis TypeInfo2(R.getParent()
+ ->getPlan()
+ ->getCanonicalIV()
+ ->getScalarType()
+ ->getContext());
assert(TypeInfo.inferScalarType(A) == TypeInfo2.inferScalarType(A));
for (VPUser *U : A->users()) {
auto *R = cast<VPRecipeBase>(U);
@@ -988,7 +991,7 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) {
void VPlanTransforms::simplifyRecipes(VPlan &Plan, Type &CanonicalIVTy) {
ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<VPBlockBase *>> RPOT(
Plan.getEntry());
- VPTypeAnalysis TypeInfo(&CanonicalIVTy);
+ VPTypeAnalysis TypeInfo(CanonicalIVTy.getContext());
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
simplifyRecipe(R, TypeInfo);
@@ -1338,7 +1341,7 @@ void VPlanTransforms::truncateToMinimalBitwidths(
// typed.
DenseMap<VPValue *, VPWidenCastRecipe *> ProcessedTruncs;
Type *CanonicalIVType = Plan.getCanonicalIV()->getScalarType();
- VPTypeAnalysis TypeInfo(CanonicalIVType);
+ VPTypeAnalysis TypeInfo(CanonicalIVType->getContext());
VPBasicBlock *PH = Plan.getVectorPreheader();
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
vp_depth_first_deep(Plan.getVectorLoopRegion()))) {
@@ -1730,8 +1733,8 @@ static VPRecipeBase *createEVLRecipe(VPValue *HeaderMask,
/// Replace recipes with their EVL variants.
static void transformRecipestoEVLRecipes(VPlan &Plan, VPValue &EVL) {
Type *CanonicalIVType = Plan.getCanonicalIV()->getScalarType();
- VPTypeAnalysis TypeInfo(CanonicalIVType);
LLVMContext &Ctx = CanonicalIVType->getContext();
+ VPTypeAnalysis TypeInfo(Ctx);
VPValue *AllOneMask = Plan.getOrAddLiveIn(ConstantInt::getTrue(Ctx));
VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
VPBasicBlock *Header = LoopRegion->getEntryBasicBlock();
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp b/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
index 3fb6a5be79ff0..64e836e35dabb 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp
@@ -73,7 +73,7 @@ class UnrollState {
public:
UnrollState(VPlan &Plan, unsigned UF, LLVMContext &Ctx)
- : Plan(Plan), UF(UF), TypeInfo(Plan.getCanonicalIV()->getScalarType()) {}
+ : Plan(Plan), UF(UF), TypeInfo(Ctx) {}
void unrollBlock(VPBlockBase *VPB);
diff --git a/llvm/lib/Transforms/Vectorize/VPlanValue.h b/llvm/lib/Transforms/Vectorize/VPlanValue.h
index 0a59b137bbd79..1fa3fbc988f5b 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanValue.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanValue.h
@@ -61,8 +61,12 @@ class VPValue {
SmallVector<VPUser *, 1> Users;
protected:
- // Hold the underlying Value, if any, attached to this VPValue.
- Value *UnderlyingVal;
+ union {
+ // Hold the underlying Value, if any, attached to this non-symbolic VPValue.
+ Value *UnderlyingVal;
+ // Hold the type of this VPValue, if it is symbolic.
+ Type *Ty;
+ };
/// Pointer to the VPDef that defines this VPValue. If it is nullptr, the
/// VPValue is not defined by any recipe modeled in VPlan.
@@ -70,8 +74,9 @@ class VPValue {
VPValue(const unsigned char SC, Value *UV = nullptr, VPDef *Def = nullptr);
- /// Create a live-in VPValue.
- VPValue(Value *UV = nullptr) : VPValue(VPValueSC, UV, nullptr) {}
+ /// Create a live-in IR VPValue.
+ VPValue(Value *UV) : VPValue(VPValueSC, UV, nullptr) {}
+ VPValue(Type *Ty) : SubclassID(VPSymbolicValueSC), Ty(Ty), Def(nullptr) {}
/// Create a VPValue for a \p Def which is a subclass of VPValue.
VPValue(VPDef *Def, Value *UV = nullptr) : VPValue(VPVRecipeSC, UV, Def) {}
/// Create a VPValue for a \p Def which defines multiple values.
@@ -86,14 +91,18 @@ class VPValue {
public:
/// Return the underlying Value attached to this VPValue.
- Value *getUnderlyingValue() const { return UnderlyingVal; }
+ Value *getUnderlyingValue() const {
+ return SubclassID == VPSymbolicValueSC ? nullptr : UnderlyingVal;
+ }
/// An enumeration for keeping track of the concrete subclass of VPValue that
/// are actually instantiated.
enum {
- VPValueSC, /// A generic VPValue, like live-in values or defined by a recipe
- /// that defines multiple values.
- VPVRecipeSC /// A VPValue sub-class that is a VPRecipeBase.
+ VPValueSC, /// A generic non-symbolic VPValue, like live-in IR values or
+ /// defined by a recipe that defines multiple values.
+ VPSymbolicValueSC, /// A generic VPValue, like live-in values or defined by
+ /// a recipe that defines multiple values.
+ VPVRecipeSC /// A VPValue sub-class that is a VPRecipeBase.
};
VPValue(const VPValue &) = delete;
@@ -172,6 +181,10 @@ class VPValue {
/// Returns true if this VPValue is a live-in, i.e. defined outside the VPlan.
bool isLiveIn() const { return !hasDefiningRecipe(); }
+ bool isSymbolic() const { return SubclassID == VPSymbolicValueSC; }
+
+ Type *getType() const;
+
/// Returns the underlying IR value, if this VPValue is defined outside the
/// scope of VPlan. Returns nullptr if the VPValue is defined by a VPDef
/// inside a VPlan.
diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
index 1b3b69ea6a13d..6c8b55a86c938 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp
@@ -415,8 +415,10 @@ bool VPlanVerifier::verify(const VPlan &Plan) {
bool llvm::verifyVPlanIsValid(const VPlan &Plan) {
VPDominatorTree VPDT;
VPDT.recalculate(const_cast<VPlan &>(Plan));
- VPTypeAnalysis TypeInfo(
- const_cast<VPlan &>(Plan).getCanonicalIV()->getScalarType());
+ VPTypeAnalysis TypeInfo(const_cast<VPlan &>(Plan)
+ .getCanonicalIV()
+ ->getScalarType()
+ ->getContext());
VPlanVerifier Verifier(VPDT, TypeInfo);
return Verifier.verify(Plan);
}
diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h b/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
index caf5d2357411d..85ac0c3ac8a75 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTestBase.h
@@ -71,7 +71,7 @@ class VPlanTestIRBase : public testing::Test {
Loop *L = LI->getLoopFor(LoopHeader);
PredicatedScalarEvolution PSE(*SE, *L);
- auto Plan = std::make_unique<VPlan>(L);
+ auto Plan = std::make_unique<VPlan>(L, IntegerType::get(*Ctx, 64));
VPlanHCFGBuilder HCFGBuilder(L, LI.get(), *Plan);
HCFGBuilder.buildHierarchicalCFG();
VPlanTransforms::introduceTopLevelVectorLoopRegion(
@@ -91,7 +91,8 @@ class VPlanTestBase : public testing::Test {
}
VPlan &getPlan(VPValue *TC = nullptr) {
- Plans.push_back(std::make_unique<VPlan>(&*ScalarHeader, TC));
+ Plans.push_back(
+ std::make_unique<VPlan>(&*ScalarHeader, TC, IntegerType::get(C, 64)));
return *Plans.back();
}
};
|
| /// Return the underlying Value attached to this VPValue. | ||
| Value *getUnderlyingValue() const { return UnderlyingVal; } | ||
| Value *getUnderlyingValue() const { | ||
| return SubclassID == VPSymbolicValueSC ? nullptr : UnderlyingVal; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return SubclassID == VPSymbolicValueSC ? nullptr : UnderlyingVal; | |
| return isSymbolic() ? nullptr : UnderlyingVal; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks!
| bool isSymbolic() const { return SubclassID == VPSymbolicValueSC; } | ||
|
|
||
| Type *getType() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need some description comments for the 2 functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks. Also updated name to getScalarType
| VPValue(Value *UV = nullptr) : VPValue(VPValueSC, UV, nullptr) {} | ||
| /// Create a live-in IR VPValue. | ||
| VPValue(Value *UV) : VPValue(VPValueSC, UV, nullptr) {} | ||
| VPValue(Type *Ty) : SubclassID(VPSymbolicValueSC), Ty(Ty), Def(nullptr) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe directly set Def to nullptr by default?
VPDef *Def = nullptr;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can do separately, as independent of the PR?
| /// Construct a VPlan for \p L. This will create VPIRBasicBlocks wrapping the | ||
| /// original preheader and scalar header of \p L, to be used as entry and | ||
| /// scalar header blocks of the new VPlan. | ||
| VPlan(Loop *L); | ||
| VPlan(Loop *L, Type *InductionTy); | ||
|
|
||
| /// Construct a VPlan with a new VPBasicBlock as entry, a VPIRBasicBlock | ||
| /// wrapping \p ScalarHeaderBB and a trip count of \p TC. | ||
| VPlan(BasicBlock *ScalarHeaderBB, VPValue *TC) { | ||
| VPlan(BasicBlock *ScalarHeaderBB, VPValue *TC, Type *InductionTy) | ||
| : VectorTripCount(InductionTy), VF(InductionTy), VFxUF(InductionTy) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to update the comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done thanks!
This introduces a new VPSymbolicValueSC to be used for typed live-in VPValues without underlying IR. VPValue is updated to store either the type or an underlying value in an union. This allows keeping the size of VPValue unchanged. The main motivation for adding the type is to not require passing the canonical IV type to VPTypeAnalysis. While with this patch, we still need to pass the LLVMContext, this can also be removed in a future patch (see 9493c38)
ed85b35 to
7f9235c
Compare
You can test this locally with the following command:git-clang-format --diff 01f04252b6711e281d9569172302ec20789e9bbe acbca4ae4a710429d21c9be1a304f3e70aa2d004 --extensions h,cpp -- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp llvm/lib/Transforms/Vectorize/VPlan.cpp llvm/lib/Transforms/Vectorize/VPlan.h llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp llvm/lib/Transforms/Vectorize/VPlanAnalysis.h llvm/lib/Transforms/Vectorize/VPlanHelpers.h llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp llvm/lib/Transforms/Vectorize/VPlanUnroll.cpp llvm/lib/Transforms/Vectorize/VPlanValue.h llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp llvm/unittests/Transforms/Vectorize/VPlanTestBase.hView the diff from clang-format here.diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 2de6f3b83c..0d795d2ad8 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -802,7 +802,6 @@ void VPlanTransforms::optimizeInductionExitUsers(
if (!isa<PHINode>(ExitIRI->getInstruction()))
break;
-
for (auto [Idx, PredVPBB] : enumerate(ExitVPBB->getPredecessors())) {
if (PredVPBB == MiddleVPBB)
if (VPValue *Escape = optimizeLatchExitInductionUser(
|
This introduces a new VPSymbolicValueSC to be used for typed live-in VPValues without underlying IR. VPValue is updated to store either the type or an underlying value in an union. This allows keeping the size of VPValue unchanged.
The main motivation for adding the type is to not require passing the canonical IV type to VPTypeAnalysis.
While with this patch, we still need to pass the LLVMContext, this can also be removed in a future patch (see
9493c38)